package com.yf.framework.aspect.log;

import com.alibaba.fastjson.JSON;
import com.yf.framework.annotation.LogInject;
import com.yf.framework.utils.IpUtils;
import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * 日志核心过滤器
 * @author bool
 */
@Log4j2
public class LogProducer {

    /**
     * 数据保存实现
     */
    private LogDataSetter logDataSetter;

    /**
     * 网络请求对象
     */
    private HttpServletRequest request;

    /**
     * 构造方法，传入需要的实现
     * @param request
     * @param setter
     */
    public LogProducer(HttpServletRequest request, LogDataSetter setter){
        this.request = request;
        this.logDataSetter = setter;
    }

    /**
     * 录制日志信息
     * @param jp
     * @return
     * @throws Throwable
     */
    public Object record(ProceedingJoinPoint jp) throws Throwable {

        // 请求地址
        String uri = request.getRequestURI();

        log.info("++++++++++注入日志信息：" + request.getRequestURI());

        // IP地址
        String ip = IpUtils.extractClientIp(request);

        Method method = ((MethodSignature) jp.getSignature()).getMethod();

        //接口参数
        Object [] params = jp.getArgs();

        //解析注入信息
        LogInject ann = method.getAnnotation(LogInject.class);

        // 执行返回
        boolean success = true;
        String log = "";
        Object objet = null;
        Exception e = null;
        try{
            objet = jp.proceed();
        }catch (Exception e1){
            e = e1;
            success = false;
            e.printStackTrace();
            log = e.getMessage();
        }


        // 保存日志，一定使用异步方法，避免阻塞主线程
        logDataSetter.saveLog(ann.logType(), uri, ann.title(), ip, JSON.toJSONString(params), success, log, objet);

        // 存在异常，抛出
        if(!success){
            throw e;
        }

        return objet;
    }

}
